package application;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import application.HibernateUtil;
import application.beans.CompteBean;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;

/**
 *
 * @author Étienne
 */
class CompteDAO {
    
    /**
     * Fonction qui sert à aller chercher un compte dans la base de données à
     * partir de son id.
     * @param id
     * @return le compte trouvé ou null s'il n'existait pas.
     */
    public Compte chercherCompte(Integer id){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Compte compte = (Compte) (session.load(Compte.class, id));
        return compte;        
    }
    
    /**
     * Fonction qui sert à aller chercher un comtpe dans la base de données à 
     * partir de son nom d'utilisateur
     * @param username
     * @return compte trouvé
     */
    public Compte chercherAvecUsername(String username){
        // On va chercher la session
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Compte compte = null;

        Query query = session.createQuery("FROM Compte WHERE "
                + "username = :username AND actif='O'");
        query.setParameter("username", username);
        if(!(query.list().isEmpty())){
            compte = (Compte)query.list().get(0);
        }
        
        return compte;
    }
    
    public List<Cours> chercherCoursProfesseur(Integer idProf){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Query query = session.createSQLQuery("SELECT * FROM Cours "
                + "WHERE id_prof = :idProf")
                .addEntity(application.Cours.class);
        query.setParameter("idProf", idProf);
        List<Cours> resultats = query.list();
        
        return resultats;
    }
    
    /**
     * Fonction servant à aller chercher les comptes dans la base de données
     * qui sont des professeurs dans le domaine passé en paramètre.
     * @param domaine
     * @return 
     */
    public List<Compte> chercherProfesseurs(String domaine){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Query query = session.createQuery("FROM Compte WHERE statut = "
                + "'professeur' AND domaineEtude LIKE :domaine");
        query.setParameter("domaine", "%" + domaine + "%");
        List<Compte> resultats = query.list();
        
        return resultats;
    }
    
    
    /**
     * Fonction servant à faire la recherche de comtpe selon le nom et le statut
     * du compte passés en paramètre.
     * @param nom
     * @param statut
     * @return 
     */
    public List<Compte> rechercheComptes(String nom, String statut){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Query query = session.createQuery("FROM Compte WHERE (LOWER(username)"
                + " LIKE :nom OR LOWER(nomComplet) LIKE :nom) "
                + "AND statut LIKE :statut AND actif='O'");
        query.setParameter("nom", "%" + nom + "%");
        query.setParameter("statut", "%" + statut + "%");
        List<Compte> resultats = query.list();
        
        return resultats;
    }
    
    /**
     * Fonction qui va chercher le mot de passe d'un compte selon l'id du compte
     * @param id
     * @return le mot de passe encrypté
     */
    public String chercherPasswordCompte(Integer id){
        String password = "";
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Query query = session.createSQLQuery("SELECT PASSWORD FROM COMPTE WHERE"
                 + " ID_COMPTE = :idCompte");
        query.setParameter("idCompte", id);
        ArrayList<String> donneesCompte = (ArrayList<String>)query.list();
        password = donneesCompte.get(0);
        return password;
    }
    
    /**
     * Fonction servant à aller chercher les comptes dans la base de données 
     * correspondant aux critères passés en paramètre.
     * @param criteres
     * @return liste des comptes trouvés
     */
    public List<Compte> rechercheComptesAvancee(CompteBean criteres){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        String requete = "SELECT * FROM v_compte WHERE LOWER(username)"
                + " LIKE :username AND LOWER(nom_complet) LIKE :nom AND "
                + "LOWER(code_permanent) LIKE :code ORDER BY username";
        
        /*
         * S'il y a un domaine, un statut ou un sexe, on l'ajoute comme critère
         * de recherche
         */
        if(criteres.getDomaineEtude() != null 
                && !(criteres.getDomaineEtude().equals(""))){
            requete +=  " AND domaine = :domaine ";
        }
        if(criteres.getStatut() != null && !(criteres.getStatut().equals(""))){
            requete +=  " AND type_compte = :statut ";
        }
        if(criteres.getSexe() != null && !(criteres.getSexe().equals(""))){
            requete +=  " AND sexe = :sexe ";
        }
        /*
         * Si des critères de chaînes de caractères sont à null,
         * on les mets vides
         */
        if(criteres.getUsername() == null){criteres.setUsername("");}
        if(criteres.getNomComplet() == null){criteres.setNomComplet("");}
        if(criteres.getCodePermanent() == null){criteres.setCodePermanent("");}
        
        Query query = session.createSQLQuery(requete)
                .addEntity(application.Compte.class);
        
        query.setParameter("username", "%" + criteres.getUsername() + "%");
        query.setParameter("nom", "%" + criteres.getNom() + "%");
        query.setParameter("code", "%" + criteres.getCodePermanent() + "%");
        
        // S'il y a un domaine, un statut ou un sexe, on ajoute le paramètre
        if(criteres.getDomaineEtude() != null 
                && !(criteres.getDomaineEtude().equals(""))){
            query.setParameter("domaine", criteres.getDomaineEtude());
        }
        if(criteres.getStatut() != null && !(criteres.getStatut().equals(""))){
            query.setParameter("statut", criteres.getStatut());
        }
        if(criteres.getSexe() != null && !(criteres.getSexe().equals(""))){
            query.setParameter("sexe", criteres.getSexe());
        }
        
        List<Compte> resultats = query.list();
        
        return resultats;
    }
    
    /**
     * Procédure servant à écrire un compte dans la base de données à partir des
     * informations passées en paramètre
     * @param infos 
     * @param password 
     */
    public void ecrireCompte(CompteBean infos, String password){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();  
  
        Query query = session.createSQLQuery("insert into COMPTE(username,"
                  + " password, nom, prenom, courriel, FK_ID_DOMAINE, "
                  + "FK_ID_TYPE_COMPTE, sexe, code_permanent) values("
                  + ":username, "
                  + ":password, "
                  + ":nom, "
                  + ":prenom, "
                  + ":courriel, "
                  + ":domaine, "
                  + ":statut, "
                  + ":sexe, "
                  + ":codePermanent)");

        query.setParameter("username",infos.getUsername());
        query.setParameter("password",password);
        query.setParameter("nom",infos.getNom());
        query.setParameter("prenom",infos.getPrenom());
        query.setParameter("courriel",infos.getCourriel());
        query.setParameter("domaine",chercherDomaineEtude(
                                                      infos.getDomaineEtude()));
        query.setParameter("statut",chercherStatut(infos.getStatut()));
        query.setParameter("sexe",infos.getSexe());
        query.setParameter("codePermanent",infos.getCodePermanent());
        query.executeUpdate();
        session.getTransaction().commit();
    }
    
    /**
     * Procédure servant à mettre à jour un compte dans la base de données à 
     * partir des informations passées en paramètre.
     * @param compte 
     */
    public void miseAJourCompte(CompteBean infos){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();  
        
        Query query = session.createSQLQuery("UPDATE COMPTE SET nom = :nom,"
                  + "prenom =:prenom, courriel = :courriel, "
                  + "FK_ID_DOMAINE = :domaine, FK_ID_TYPE_COMPTE = :statut, "
                  + "sexe = :sexe, code_permanent = :code, actif = :actif "
                  + "WHERE id_compte = :idCompte");

        query.setParameter("idCompte",infos.getIdCompte());
        query.setParameter("nom",infos.getNom());
        query.setParameter("prenom",infos.getPrenom());
        query.setParameter("courriel",infos.getCourriel());
        query.setParameter("domaine",chercherDomaineEtude(
                                                      infos.getDomaineEtude()));
        query.setParameter("statut",chercherStatut(infos.getStatut()));
        query.setParameter("sexe",infos.getSexe());
        query.setParameter("code",infos.getCodePermanent());
        query.setParameter("actif",infos.getActif());
        query.executeUpdate();
        session.getTransaction().commit();
    }
    
    /**
     * Fonction qui va chercher l'id d'un domaine d'étude selon son nom, passé
     * en paramètre.
     * @param nom
     * @return l'id du domaine d'étude
     */
    public Integer chercherDomaineEtude(String nom){
        Integer idDomaine = 0;
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Query query = session.createSQLQuery("SELECT ID_DOMAINE FROM"
                + " DOMAINES_ETUDE WHERE NOM = :nom");
        query.setParameter("nom", nom);
        List<Integer> temp = query.list();
        // S'il est introuvable, le domaine sera "aucun"
        if(!temp.isEmpty()){idDomaine = temp.get(0);}
        
        return idDomaine;
    }
    
    /**
     * Fonction qui va chercher l'id d'un statut(type de compte) selon son nom,
     * passé en paramètre.
     * @param nom
     * @return l'id du statut
     */
    public Integer chercherStatut(String nom){
        Integer idStatut = 0;
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Query query = session.createSQLQuery("SELECT ID_TYPE_COMPTE FROM"
                + " TYPE_COMPTE WHERE NOM = :nom");
        query.setParameter("nom", nom);
        List<Integer> temp = query.list();
        // S'il est introuvable, le domaine sera "aucun"
        if(!temp.isEmpty()){idStatut = temp.get(0);}
        
        return idStatut;
    }
    
}
